package com.sa.token.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sa.token.dto.request.role.*;
import com.sa.token.dto.response.role.RoleByUserIdResponse;
import com.sa.token.entity.SysRoleEntity;
import com.sa.token.entity.SysRoleMenuEntity;
import com.sa.token.mapper.SysRoleMapper;
import com.sa.token.mapper.SysUserRoleMapper;
import com.sa.token.message.Result;
import com.sa.token.message.StandardResponse;
import com.sa.token.service.SysRoleMenuService;
import com.sa.token.service.SysRoleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 角色表 服务实现类
 * </p>
 *
 * @author xhs
 * @since 2021-08-27
 */
@Service
public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRoleEntity> implements SysRoleService {

    @Autowired
    private SysRoleMenuService roleMenuService;
    @Resource
    private SysUserRoleMapper roleMapper;

    /**
     * 查询角色接口
     *
     * @param rolePageRequest
     * @return
     */
    @Override
    public StandardResponse selectRole(RolePageRequest rolePageRequest) {
        Page page = new Page<>(rolePageRequest.getCurrent(), rolePageRequest.getSize());
        LambdaQueryWrapper<SysRoleEntity> queryWrapper = new QueryWrapper<SysRoleEntity>().lambda()
                .eq(SysRoleEntity::getDelFlg, "0")
                .like(StringUtils.hasLength(rolePageRequest.getRoleNm()), SysRoleEntity::getRoleNm, rolePageRequest.getRoleNm())
                .eq(StringUtils.hasLength(rolePageRequest.getRoleStatus()), SysRoleEntity::getRoleStatus, rolePageRequest.getRoleStatus());
        Page list = getBaseMapper().selectPage(page, queryWrapper);
        return StandardResponse.build(Result.QUERY_SUCCESS).setData(list);
    }

    /**
     * 新增角色接口
     *
     * @param request
     * @param roleRequest
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public StandardResponse insertRole(HttpServletRequest request, InsertRoleRequest roleRequest) {
        // 1.验证角色是否存在
        LambdaQueryWrapper<SysRoleEntity> queryWrapper = new QueryWrapper<SysRoleEntity>().lambda()
                .eq(SysRoleEntity::getDelFlg, '0')
                .ne(SysRoleEntity::getRoleNm, roleRequest.getRoleNm());
        SysRoleEntity roleEntity = getBaseMapper().selectOne(queryWrapper);
        if(roleEntity != null){
            return StandardResponse.build(Result.ROLE_EXIST_ERROR);
        }
        SysRoleEntity build = SysRoleEntity.builder()
                .roleNm(roleRequest.getRoleNm())
                .roleSort(roleRequest.getRoleSort())
                .roleStatus(roleRequest.getRoleStatus())
                .creator(StpUtil.getLoginIdAsString())
                .build();
        // 新增角色
        boolean save = save(build);
        if (save) {
            return StandardResponse.build(Result.ADD_SUCCESS);
        } else {
            return StandardResponse.build(Result.ADD_ERROR);
        }
    }

    /**
     * 删除角色
     *
     * @param request
     * @param delRoleRequest
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public StandardResponse delRole(HttpServletRequest request, DelRoleRequest delRoleRequest) {
        LambdaQueryWrapper<SysRoleEntity> queryWrapper = new QueryWrapper<SysRoleEntity>().lambda()
                .eq(SysRoleEntity::getDelFlg, "0")
                .eq(SysRoleEntity::getId, delRoleRequest.getId());
        SysRoleEntity roleEntity = getBaseMapper().selectOne(queryWrapper);
        if (roleEntity == null) {
            return StandardResponse.build(Result.DEl_ERROR);
        }
        roleEntity.setDelFlg(1);
        roleEntity.setUpdater(StpUtil.getLoginIdAsString());
        boolean update = updateById(roleEntity);
        if (update) {
            return StandardResponse.build(Result.DEl_SUCCESS);
        } else {
            return StandardResponse.build(Result.DEl_ERROR);
        }
    }

    /**
     * 编辑角色接口
     *
     * @param request
     * @param updateRoleRequest
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public StandardResponse updateRole(HttpServletRequest request, UpdateRoleRequest updateRoleRequest) {
        // 1.验证角色是否存在
        LambdaQueryWrapper<SysRoleEntity> query = new QueryWrapper<SysRoleEntity>().lambda()
                .eq(SysRoleEntity::getDelFlg, '0')
                .eq(SysRoleEntity::getRoleNm, updateRoleRequest.getRoleNm())
                .ne(SysRoleEntity::getId, updateRoleRequest.getId());
        SysRoleEntity role = getBaseMapper().selectOne(query);
        if(role != null){
            return StandardResponse.build(Result.ROLE_EXIST_ERROR);
        }
        LambdaQueryWrapper<SysRoleEntity> queryWrapper = new QueryWrapper<SysRoleEntity>().lambda()
                .eq(SysRoleEntity::getDelFlg, "0")
                .eq(SysRoleEntity::getId, updateRoleRequest.getId());
        SysRoleEntity roleEntity = getBaseMapper().selectOne(queryWrapper);
        if (roleEntity == null) {
            return StandardResponse.build(Result.UPD_ERROR);
        }
        roleEntity.setRoleNm(updateRoleRequest.getRoleNm());
        roleEntity.setRoleSort(updateRoleRequest.getRoleSort());
        roleEntity.setRoleStatus(updateRoleRequest.getRoleStatus());
        roleEntity.setUpdater(StpUtil.getLoginIdAsString());
        boolean update = updateById(roleEntity);
        if (update) {
            return StandardResponse.build(Result.UPD_SUCCESS);
        } else {
            return StandardResponse.build(Result.UPD_ERROR);
        }
    }

    /**
     * 根据id查询角色接口
     *
     * @param request
     * @param delRoleRequest
     * @return
     */
    @Override
    public StandardResponse getRoleById(HttpServletRequest request, DelRoleRequest delRoleRequest) {
        LambdaQueryWrapper<SysRoleEntity> queryWrapper = new QueryWrapper<SysRoleEntity>().lambda()
                .eq(SysRoleEntity::getDelFlg, "0")
                .eq(SysRoleEntity::getId, delRoleRequest.getId());
        SysRoleEntity roleEntity = getBaseMapper().selectOne(queryWrapper);
        return StandardResponse.build(Result.QUERY_SUCCESS).setData(roleEntity);
    }

    /**
     * 根据角色Id查询权限接口
     *
     * @param permissionsRequest
     * @return
     */
    @Override
    public StandardResponse getPermissions(SelectPermissionsRequest permissionsRequest) {
        LambdaQueryWrapper<SysRoleMenuEntity> queryWrapper = new QueryWrapper<SysRoleMenuEntity>().lambda()
                .eq(SysRoleMenuEntity::getRoleId, permissionsRequest.getRoleId());
        List<SysRoleMenuEntity> roleEntityList = roleMenuService.getBaseMapper().selectList(queryWrapper);
        List<Integer> list = new ArrayList<>();
        if (roleEntityList.size() > 0 && roleEntityList != null) {
            for (SysRoleMenuEntity roleEntity : roleEntityList) {
                list.add(roleEntity.getPermissionId());
            }
            return StandardResponse.build(Result.QUERY_SUCCESS).setData(list);
        }
        return StandardResponse.build(Result.QUERY_SUCCESS);
    }

    /**
     * 分配权限
     *
     * @param permissionsRequest
     * @return
     */
    @Override
    public StandardResponse addPermissions(AssignPermissionRequest permissionsRequest) {
        // 1.检查角色是否存在
        LambdaQueryWrapper<SysRoleEntity> eq = new QueryWrapper<SysRoleEntity>().lambda()
                .eq(SysRoleEntity::getDelFlg, "0")
                .eq(SysRoleEntity::getId, permissionsRequest.getRoleId());
        SysRoleEntity roleEntity = getBaseMapper().selectOne(eq);
        if (roleEntity == null) {
            return StandardResponse.build(Result.ROLE_NOT_EXIST_ERROR);
        }
        // 2.菜单为空，则清空勾选的菜单
        LambdaQueryWrapper<SysRoleMenuEntity> queryWrapper = new QueryWrapper<SysRoleMenuEntity>().lambda()
                .eq(SysRoleMenuEntity::getRoleId, permissionsRequest.getRoleId());
        if (permissionsRequest.getMenuList().size() == 0) {
            boolean remove = roleMenuService.remove(queryWrapper);
            if (remove) {
                return StandardResponse.build(Result.ASSIGN_PERMISSIONS_SUCCESS);
            } else {
                return StandardResponse.build(Result.ASSIGN_PERMISSIONS_ERROR);
            }
        }
        // 3.先清空之前的权限，再重新分配权限，以最新的为准
        roleMenuService.remove(queryWrapper);
        // 4.分配权限
        List<SysRoleMenuEntity> roleMenuList = new ArrayList<>();
        for (Integer menu : permissionsRequest.getMenuList()) {
            SysRoleMenuEntity roleMenu = new SysRoleMenuEntity();
            roleMenu.setRoleId(permissionsRequest.getRoleId());
            roleMenu.setPermissionId(menu);
            roleMenuList.add(roleMenu);
        }
        roleMenuService.saveBatch(roleMenuList);
        return StandardResponse.build(Result.ASSIGN_PERMISSIONS_SUCCESS);
    }

    /**
     * 查询角色
     *
     * @return
     */
    @Override
    public StandardResponse getRole() {
        LambdaQueryWrapper<SysRoleEntity> queryWrapper = new QueryWrapper<SysRoleEntity>().lambda()
                .eq(SysRoleEntity::getDelFlg, "0");
        List<SysRoleEntity> roleEntities = getBaseMapper().selectList(queryWrapper);
        return StandardResponse.build(Result.QUERY_SUCCESS).setData(roleEntities);
    }

    /**
     * 根据用户ID查询角色
     *
     * @param queryRoleRequest
     * @return
     */
    @Override
    public StandardResponse getRoleByUserId(QueryRoleRequest queryRoleRequest) {
        List<RoleByUserIdResponse> roleByUserId = roleMapper.getRoleByUserId(queryRoleRequest.getUserId());
        return StandardResponse.build(Result.QUERY_SUCCESS).setData(roleByUserId);
    }
}
